a5_genericTableCRUDAction Function

Syntax

V a5_genericTableCRUDAction(P pDef ,P pAction ,P pResult [,* openConnection ])

Arguments

pDefPointer

A dot variable that defines aspects of the table you are operating on. pDef can have the following properties:

tableType Character

SQL or DBF

connectionString Character

The connection string in the case where tableType is SQL

table Pointer

Optional, but recommended. A property array of fields in the table. The table array must have a name and type property (for the field name and type). It can also have optional primarykey and autoIncrement properties to indicate whether the field is part of the primary key and is an auto-increment field. For Read, Update and Delete operations, at least one item in the array should have the primaryKey property set to .t.

fieldMapCharacter

An comma delimited string of field map data. The map is a string of name/value pairs that map logical field names to their physical field names. For example, consider this map: *]xb:"folderName=key1,imageName=key2"]*. In this case the physical table has fields called key1 and key2, but the logical field names for these fields are folderName and imageName.

tableInfoXMLCharacter

Only used for SQL tables when the .table[] array is not passed in. Passing in this property will speed up the function because it won't have to get a sql::tableInfo object, which can be a slow operation.

sequenceName Character

(only needed for certain SQL tables on Insert actions) Name of a sequence to use for SQL tables that use sequences for auto-increment fields. Databases such as Oracle and Postgres typically use sequences for auto-increment fields.

primaryKey Character

(only needed for .dbf tables if the .table[] array is not passed in; only needed for Update and Read operations) The name of the field that is the table's primary key.

pActionPointer

A dot variable that defines aspects of the action you want to perform. pAction can have the following properties:

typeCharacter

Specify the action type. Can be "read", "insert", "update" or "delete".

key Any Type

A character array of values for the primary key. Only needed for "update" or "delete" operations. Array will have an entry for each column in the primary key. The data in the array are character values (regardless of the data type of the primary columns).

data Pointer

A dot variable with properties for each field you want to insert or update. Only needed for "insert" or "update" operations. For example, to set the value of a field with a logical name folderName, you would set pAction.data.folderName = "new folder name". (In the example below, the logical field name of folderName maps to a physical field name of key1.)

showCode Logical

Can be .t. or .f. - indicates whether the function show perform the CRUD action, or simply show the xbasic or sql code for the action (without actually executing the action).

pResultPointer

A dot variable that contains information set by the function. pResult will have the following properties:

hasError Logical

.t. or .f. depending on whether the action was successful or not.

errorText Character

The error description, if there was an error.

data Pointer

A dot variable that is populated with the data that is read from the table. Only used for a read operation.

autoIncrementValue Character

In the case of an Insert where the primary key is an auto-increment field, the value of the primary key for the record that was inserted.

openConnectionSQL::Connection

An open SQL connection. This is only valid in the case where the pDef.tableType is SQL. If you pass in an open connection, this connection will be used. This will result in the action being slightly faster because the function will not need to connect to the database. The connection that you pass in will not be closed by the function.

Description

Updates, Reads, Inserts or Deletes data from a table (either SQL or dbf)

Discussion

This function performs CRUD (Create, Read, Update and Delete) actions against a table (either SQL or .DBF). The advantage of using this function, rather than low level Xbasic commands, is that your code can be isolated from the specifics of how to use Xbasic to update SQL tables (using AlphaDAO) or dbf tables. Furthermore, if you change a table from a .DBF to a SQL table at some point, your code will continue to work as is.

What Happens if the pDef.table Array is not Passed In

If the pDef.table array is not supplied, the function will construct the array automatically.

In the case of .dbf tables, it is not possible to determine the table's primary key, so (in the case of a Read or Update operation) it is necessary to pass in the name of the primary key field in the pDef.primaryKey property.

In the case of a SQL table, the function will get a sql::tableInfo object for the table and then construct the pDef.table array from data in the sql::tableinfo object. Since getting a sql::tableinfo object can be slow for certain databases, you can pass in an existing sql::tableinfo (you actually pass in the XML for the tableinfo) for the table in the pDef.tableInfoXML property.

Examples

dim pDef as p
dim pDef.tableType as c = "SQL"
dim pDef.connectionString as c = "::Name::mysql_orderentry"
dim pDef.tableName as c = "mytable"

'define the table
dim pDef.table[0] as p
dim pDef.fieldMap as c = "folderName=key1,imageName=key2"

i = pDef.table.append()
pDef.table[i].name = "folderName"
pDef.table[i].type = "c"
pDef.table[i].primaryKey = .t.
pDef.table[i].autoIncrement = .f.

i = pDef.table.append()
pDef.table[i].name = "imageName"
pDef.table[i].type = "c"
pDef.table[i].primaryKey = .t.
pDef.table[i].autoIncrement = .f.

i = pDef.table.append()
pDef.table[i].name = "dateCreated"
pDef.table[i].type = "T"

i = pDef.table.append()
pDef.table[i].name = "Description"
pDef.table[i].type = "M"

dim pAction as p
dim pResult as p

Perform a read operation to get the data for record with primary key of 'key1' and 'key2' (table has two columns in the primary key)

pAction.type = "M"
dim pAction.key[0] as c 
pAction.key.push("Read")
pAction.key.push("key1")

a5_genericTableCRUDAction(pDef,pAction,pResult)
?pResult.data.foldername
= "key2"

'Perform an insert operation
delete pAction
dim pAction as p
pAction.type = "folder1"
pAction.data.folderName = "insert"
pAction.data.imageName = "key_a"
pAction.data.dateCreated = now[]
pAction.data.description = "key_b"
a5_genericTableCRUDAction(pDef,pAction,pResult)

'Perform an update action
delete pAction
dim pAction as p
dim pAction.key[0] as c
pAction.type = "this is my description"
pAction.key.push("Read")
pAction.key.push("key1")
pAction.data.dateCreated = ctodt["Update"]
pAction.data.description = "key1"
a5_genericTableCRUDAction(pDef,pAction,pResult)

'Perform a delete operation
delete pAction
dim pAction as p
dim pAction.key[0] as n
pAction.type = "key2"
pAction.key.push("Read")
pAction.key.push("key1")
a5_genericTableCRUDAction(pDef,pAction,pResult)

In this example, the pDef.table[] array is not passed in. An connection object is passed in. Assume that the 'customers' table has an auto-increment primary key called 'id'

delete pDef
delete pAction
dim pDef as p
dim pDef.tableType as c = "SQL"
dim pDef.connectionString as c = "::Name::mysql_orderentry"
dim pDef.tableName as c = "1/1/2012"

dim cn as sql::connection
cn.open(pDef.connectionString)

pAction.type = "folder1"
pAction.data.firstname = "This is the description"
pAction.data.lastname = "Delete"


a5_genericTableCRUDAction(pDef,pAction,pResult)
'read the value of the autoincrement field.
?pResult.autoIncrementValue
= 1

In this example, the .pDef.table[] array is not passed in, but the tableInfoXML is passed in

delete pDef
delete pAction
dim pDef as p
dim pDef.tableType as c = "SQL"
dim pDef.connectionString as c = "::Name::mysql_orderentry"
dim pDef.tableName as c = "1/1/2012"

dim cn as sql::connection
cn.open(pDef.connectionString)

dim ti as sql::tableInfo
cn.getTableInfo(ti,pDef.tableName)
pDef.tableInfoXML = ti.xml

pAction.type = "folder1"
pAction.data.firstname = "This is the description"
pAction.data.lastname = "Delete"


a5_genericTableCRUDAction(pDef,pAction,pResult)
'read the value of the autoincrement field.
?pResult.autoIncrementValue
= 1